package com.zcoj.controller.User.judge;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.zcoj.core.model.ApiResponse;
import com.zcoj.core.model.PageWrap;
import com.zcoj.judgeServer.pojo.DTO.TestJudgeReq;
import com.zcoj.judgeServer.pojo.DTO.ToJudgeDTO;
import com.zcoj.judgeServer.service.judge.OpenJudgeService;
import com.zcoj.pojo.Dto.Contest;
import com.zcoj.pojo.Dto.ContestRecord;
import com.zcoj.pojo.Dto.Judge;
import com.zcoj.security.dto.LoginUser;
import com.zcoj.service.ContestRecordService;
import com.zcoj.service.ContestService;
import com.zcoj.service.JudgerService;
import com.zcoj.util.RedisCaches;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.Objects;

/**
 * 接口
 * @author 剩xia的盛夏
 * @date 2023/02/24 16:16
 */
@RestController
@RequestMapping("/judge")
@Api(tags = "接口")
public class JudgeController {

    @Autowired
    private JudgerService judgerService;

    @Autowired
    private OpenJudgeService openJudgeService;

    @Autowired
    private RedisCaches redisCaches;

    @Autowired
    private ContestService contestService;


    @Autowired
    private ContestRecordService contestRecordService;

    @GetMapping("/version")
    public ApiResponse version(){
        return openJudgeService.getVersion();
    }

    @PostMapping("/submitCode")
    public ApiResponse submitCode(@RequestBody Judge judge){
        LoginUser loginUser = redisCaches.getLoginUser();
        Date date = new Date();
        Contest contest=null;
        Date startTimeTemp=null;
        if(Objects.nonNull(judge.getCid())&&judge.getCid()!=0){
            contest = contestService.findById(judge.getCid());
            startTimeTemp=contest.getStartTime();
        }

        if(!(loginUser.getPermission().contains("super_admin")||loginUser.getPermission().contains("admin")||loginUser.getPermission().contains("problem_admin"))){
            if(Objects.nonNull(judge.getCid())&&judge.getCid()!=0){
                if(date.getTime()>contest.getEndTime().getTime()){
                    return ApiResponse.failed("比赛已经结束，无法提交");
                }
                if(date.getTime()<contest.getStartTime().getTime()){
                    return ApiResponse.failed("比赛未开始，无法提交");
                }
            }
        }else {
            judge.setVisit(0);
        }

        judge.setUid(loginUser.getId());
        judge.setUsername(loginUser.getUsername());
        judge.setSubmitTime(date);
        judge.setLength(redisCaches.calculateCodeBytes(judge.getCode()));
        judge.setSubmitId(judgerService.create(judge));
        if(!(loginUser.getPermission().contains("super_admin")||loginUser.getPermission().contains("admin")||loginUser.getPermission().contains("problem_admin"))){
            //非管理参与排名
            if(Objects.nonNull(judge.getCid())&&judge.getCid()!=0){
                ContestRecord contestRecord = new ContestRecord();
                contestRecord.setCid(judge.getCid())
                        .setUid(loginUser.getId())
                        .setUsername(loginUser.getUsername())
                        .setRealname(loginUser.getRealname())
                        .setSubmitId(judge.getSubmitId())
                        .setSubmitTime(date)
                        .setPid(judge.getPid())
                        .setTime(DateUtil.between(startTimeTemp,date, DateUnit.MS));
                contestRecordService.create(contestRecord);
            }
        }
        ToJudgeDTO toJudgeDTO = new ToJudgeDTO();
        toJudgeDTO.setJudge(judge);
        return openJudgeService.submitProblemJudge(toJudgeDTO);
    }




    @PostMapping("/testCode")
    public ApiResponse testCode(@RequestBody TestJudgeReq testJudgeReq){
        testJudgeReq.setTimeLimit(1000).setMemoryLimit(256).setStackLimit(128).setIsRemoveEndBlank(true).setProblemJudgeMode("default");
        return openJudgeService.submitProblemTestJudge(testJudgeReq);
    }

    /**
     * 分页查询
     * @author 剩xia的盛夏
     * @date 2023/02/24 16:16
     */
    @PostMapping("/page")
    @ApiOperation("分页查询")
    public ApiResponse findPage (@RequestBody PageWrap<Judge> pageWrap) {
        return ApiResponse.success(judgerService.findPage(pageWrap));
    }


    @PostMapping("/findPageVo")
    @ApiOperation("分页查询")
    public ApiResponse findPageVo(@RequestBody PageWrap<Judge> pageWrap){
        LoginUser loginUser = redisCaches.getLoginUser();
        if(!(loginUser.getPermission().contains("super_admin")||loginUser.getPermission().contains("admin")||loginUser.getPermission().contains("problem_admin"))){
            pageWrap.getModel().setVisit(1);
        }
        return ApiResponse.success(judgerService.findPageVo(pageWrap));
    }

    @GetMapping("/judgeResult")
    private ApiResponse findAllJudgeResult(){
        return ApiResponse.success(judgerService.findAllJudgeResult());
    }


    /**
     * @method: [ownerSubmitJudgeList]
     * @param: []
     * @returns: com.zcoj.core.model.ApiResponse
     * @description:  查找
     * @author: chen.bin
     * @version: 1.0.0
     * @date 2023/5/7 15:30
     **/
    @PostMapping("/ownerSubmitJudgeList")
    public ApiResponse ownerSubmitJudgeList(@RequestBody Judge judge){
        LoginUser loginUser = redisCaches.getLoginUser();
        judge.setUid(loginUser.getId());
        return ApiResponse.success(judgerService.findList(judge));
    }
    /**
     * 通过ID查询
     * @author 剩xia的盛夏
     * @date 2023/02/24 16:16
     */
    @GetMapping("/{id}")
    @ApiOperation("根据ID查询")
    public ApiResponse finById(@PathVariable Integer id) {
        return ApiResponse.success(judgerService.findById(id));
    }


    @GetMapping("/getJudgeDetail/{sid}")
    public ApiResponse getJudgeDetail(@PathVariable Integer sid){
        Judge judge = judgerService.findById(sid);
        if(!Objects.nonNull(judge)){
            return ApiResponse.failed("测评信息不存在");
        }
        LoginUser loginUser = redisCaches.getLoginUser();
        if(loginUser.getPermission().contains("admin")||loginUser.getPermission().contains("super_admin")||loginUser.getPermission().contains("judge_admin")){
            return ApiResponse.success(judgerService.getJudgeDetail(sid));
        }else {
            if(Objects.equals(judge.getUid(), loginUser.getId())){
                return ApiResponse.success(judgerService.getJudgeDetail(sid));
            }else {
                return ApiResponse.failed("无法查看他人测试点信息");
            }
        }

    }

}
